home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 August: Tool Chest / Dev.CD Aug 95 TC / Dev.CD Aug 95 TC.toast / New System Software Extensions / QuickDraw™ GX 1.1.2 / Programming Stuff / Sample Code / Graphics Samples / Spectacle ƒ / ViewPorts.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-10  |  9.7 KB  |  395 lines  |  [TEXT/KAHL]

  1. /* 
  2.  *    ViewPorts.c
  3.  *
  4.  *    Robert Dierkes,  November 11, 1993
  5.  */
  6.  
  7. #include "graphics routines.h"
  8. #include "graphics libraries.h"
  9. #include "graphics toolbox.h"
  10.  
  11. #include "Object.h"
  12. #include "ViewPorts.h"
  13.  
  14.  
  15.  
  16. /*----------------------*/
  17. /*    Global Declarations    */
  18. /*----------------------*/
  19. gxShape                gObject,
  20.                     gLastObject,
  21.                     gFrame;
  22. boolean                gIsSquare,
  23.                     gShowFrame,
  24.                     gDoDither,
  25.                     gDoHalftone;
  26. long                gPanesPerSide;
  27.  
  28. /*------------------------------*/
  29. /*    External Declarations     */
  30. /*------------------------------*/
  31. extern    boolean        gDoAnimation;
  32. extern    boolean        gCyclePanes;
  33. extern    long        gNextCycle;
  34.  
  35.  
  36. void SetHalftone (gxViewPort vPort, fixed angle, fixed frequency, gxDotType method, gxRGBColor *pDotColor);
  37. void SetDitherOrHalftone (gxViewPort vPort, short row, short col);
  38. void SetMapping (gxViewPort vPort, short row, short col, fixed xCenter, fixed yCenter);
  39.  
  40.  
  41.     static void
  42. SetHalftone (gxViewPort    vPort,
  43.             fixed        angle,
  44.             fixed        frequency,
  45.             gxDotType        method,
  46.             gxRGBColor    *pDotColor)
  47. {
  48.     gxHalftone        tone;
  49.  
  50.     if (! gDoHalftone)
  51.         return;
  52.  
  53.     tone.angle        = angle;
  54.     tone.frequency    = frequency;
  55.     tone.method        = method;
  56.     tone.tinting    = gxLuminanceTint;
  57.  
  58.     tone.dotColor.space             = gxRGBSpace;
  59.     tone.dotColor.profile         = nil;
  60.     tone.dotColor.element.rgb     = *pDotColor;
  61.     
  62.     tone.backgroundColor.space     = gxRGBSpace;
  63.     tone.backgroundColor.profile = nil;
  64.     tone.backgroundColor.element.rgb.red   =
  65.     tone.backgroundColor.element.rgb.green =
  66.     tone.backgroundColor.element.rgb.blue  = (gxColorValue) 0xFFFF;    /* white */
  67.  
  68.     tone.tintSpace = gxRGBSpace;
  69.  
  70.     GXSetViewPortHalftone (vPort, &tone);
  71. }
  72.  
  73.  
  74.     static void
  75. SetDitherOrHalftone (gxViewPort    vPort,
  76.                      short        row,
  77.                      short        col)
  78. {
  79.     gxRGBColor    dotColor;
  80.  
  81.     switch (row % kPaneRepeat)
  82.     {
  83.     case 0:
  84.         switch (col % kPaneRepeat)
  85.         {
  86.         case 0:
  87.             SetRBGColor (dotColor, 0xFFFF, 0, 0);            /* Red */
  88.             SetHalftone (vPort, IntToFixed (0), IntToFixed (4), gxRoundDot, &dotColor);
  89.             break;
  90.         case 1:
  91.             IfSetViewPortDither (false, vPort, 1);
  92.             break;
  93.         case 2:
  94.             SetRBGColor (dotColor, 0xFFFF, 45000, 0);        /* Orange */
  95.             SetHalftone (vPort, IntToFixed (45), IntToFixed (5), gxEllipticDot, &dotColor);
  96.             break;
  97.         case 3:
  98.             IfSetViewPortDither (false, vPort, 1);
  99.             break;
  100.         }
  101.         break;
  102.  
  103.     case 1:
  104.         switch (col % kPaneRepeat)
  105.         {
  106.         case 0:
  107.             IfSetViewPortDither (gDoDither, vPort, 2);
  108.             break;
  109.         case 1:
  110.             SetRBGColor (dotColor, 60000, 60000, 0);        /* Yellow */
  111.             SetHalftone (vPort, IntToFixed (0), IntToFixed (5), gxSpiralDot, &dotColor);
  112.             break;
  113.         case 2:
  114.             IfSetViewPortDither (gDoDither, vPort, 2);
  115.             break;
  116.         case 3:
  117.             SetRBGColor (dotColor, 50000, 0, 50000);        /* Lavender */
  118.             SetHalftone (vPort, IntToFixed (135), IntToFixed (6), gxLineDot, &dotColor);
  119.             break;
  120.         }
  121.         break;
  122.  
  123.     case 2:
  124.         switch (col % kPaneRepeat)
  125.         {
  126.         case 0:
  127.             SetRBGColor (dotColor, 0, 0xFFFF, 0);            /* Green */
  128.              SetHalftone (vPort, IntToFixed (45), IntToFixed (5), gxTriangleDot, &dotColor);
  129.             break;
  130.         case 1:
  131.             IfSetViewPortDither (gDoDither, vPort, 3);
  132.             break;
  133.         case 2:
  134.             SetRBGColor (dotColor, 0, 55000, 65000);        /* Cyan */
  135.             SetHalftone (vPort, IntToFixed (45), IntToFixed (4), gxSquareDot, &dotColor);
  136.             break;
  137.         case 3:
  138.             IfSetViewPortDither (gDoDither, vPort, 3);
  139.             break;
  140.         }
  141.         break;
  142.  
  143.     case 3:
  144.         switch (col % kPaneRepeat)
  145.         {
  146.         case 0:
  147.             IfSetViewPortDither (gDoDither, vPort, 4);
  148.             break;
  149.         case 1:
  150.             SetRBGColor (dotColor, 0, 0, 0xFFFF);            /* Blue */
  151.             SetHalftone (vPort, IntToFixed (45), IntToFixed (6), gxLineDot, &dotColor);
  152.             break;
  153.         case 2:
  154.             IfSetViewPortDither (gDoDither, vPort, 4);
  155.             break;
  156.         case 3:
  157.             SetRBGColor (dotColor, 40000, 40000, 40000);    /* Gray */
  158.             SetHalftone (vPort, IntToFixed (0), IntToFixed (6), gxTriangleDot, &dotColor);
  159.             break;
  160.         }
  161.         break;
  162.     }
  163. }
  164.  
  165.  
  166.     static void
  167. SetMapping (gxViewPort    vPort,
  168.             short        row,
  169.             short        col,
  170.             fixed        xCenter,
  171.             fixed        yCenter)
  172. {
  173.     gxMapping        map;
  174.  
  175.     ResetMapping (&map);
  176.  
  177.     if ((row % kPaneRepeat == 0  ||  row % kPaneRepeat == 1)  &&
  178.         (col % kPaneRepeat == 2  ||  col % kPaneRepeat == 3))
  179.             ScaleMapping (&map, fixed1, fixed1 >> 1, xCenter, yCenter);
  180.     else
  181.     if ((row % kPaneRepeat == 2  ||  row % kPaneRepeat == 3)  &&
  182.         (col % kPaneRepeat == 0  ||  col % kPaneRepeat == 1))
  183.             ScaleMapping (&map, fixed1 >> 1, fixed1, xCenter, yCenter);
  184.     else
  185.     if ((row % kPaneRepeat == 1  ||  row % kPaneRepeat == 2)  &&
  186.         (col % kPaneRepeat == 1  ||  col % kPaneRepeat == 2))
  187.             RotateMapping (&map, IntToFixed (30), xCenter, yCenter);
  188.  
  189.     GXSetViewPortMapping (vPort, &map);
  190. }
  191.  
  192.  
  193.     void
  194. ChangeFrame (Rect *pBounds, long numCols, long numRows, boolean showFrame, gxShape *pFrame)
  195. {
  196.     register
  197.     short        r, c;
  198.     register
  199.     fixed        left,
  200.                 top,
  201.                 width,
  202.                 height;
  203.     gxShape        pane;
  204.     Rect        bounds;
  205.  
  206.     DisposeShapeAt (pFrame);
  207.     if (! showFrame)
  208.         return;
  209.  
  210.     /* Find width and height of each pane */
  211.     bounds = *pBounds;
  212.     InsetRect (&bounds, FixedToInt (kFrameThickness), FixedToInt (kFrameThickness));
  213.     width    = IntToFixed (bounds.right  - bounds.left) / numCols;
  214.     height    = IntToFixed (bounds.bottom - bounds.top)  / numRows;
  215.  
  216.     /* Start with the outside frame */
  217.     *pFrame = GXNewShape (gxEmptyType);
  218.  
  219.     for (r = 0, top = kFrameThickness; r < numRows; r++)
  220.     {
  221.         for (c = 0, left = kFrameThickness; c < numCols; c++)
  222.         {
  223.             /* Add a pane inside the frame */
  224.             pane = NewShape4 (gxRectangleType, left, top, left + width, top + height);
  225.             GXInsetShape (pane, kFrameThickness);
  226.             AddToShape (*pFrame, pane);
  227.             GXDisposeShape (pane);
  228.  
  229.             left += width;
  230.         }
  231.         top += height;
  232.     }
  233.  
  234.     /* Set other characteristics on the frame */
  235.     SetShapeCommonColor (*pFrame, gxGray);
  236.     GXSetShapeStyleAttributes (*pFrame, gxOutsideFrameStyle);
  237.     GXSetShapeFill (*pFrame, gxClosedFrameFill);
  238.     GXSetShapePen (*pFrame, kFrameThickness << 1);
  239.  
  240.     /* Make the frame a picture so the grow box can be added */
  241.     GXSetShapeType (*pFrame, gxPictureType);
  242.  
  243.     /* Make a grow box in the lower left corner */
  244.     pane = NewShape4 (gxRectangleType, IntToFixed (pBounds->right)  - (kFrameThickness << 1),
  245.                                      IntToFixed (pBounds->bottom) - (kFrameThickness << 1),
  246.                                      IntToFixed (pBounds->right),
  247.                                      IntToFixed (pBounds->bottom));
  248.     SetShapeCommonColor (pane, steel);
  249.     AddToPicture (*pFrame, pane, nil, nil, nil);
  250.     GXDisposeShape (pane);
  251. }
  252.  
  253.  
  254.     static void
  255. ChangeShapeViewPorts (WindowPtr pWindow, long numRows, long numCols,
  256.                         boolean showFrame, gxShape object)
  257. {
  258.     register
  259.     short        r, c;
  260.     register
  261.     gxViewPort    *pViewPort,
  262.                 *p1stViewPort;
  263.     fixed        width,
  264.                 height,
  265.                 left,
  266.                 top;
  267.     gxShape        clip;
  268.     gxViewPort    parent;
  269.     gxTransform    xForm;
  270.     Rect        bounds;
  271.  
  272.     if (numRows == 0  ||  numCols == 0)
  273.     {
  274.         DebugStr ("\pAddViewPortsToTransform: Number of rows or columns is zero");
  275.         return;
  276.     }
  277.  
  278.     /* Find width and height of each gxViewPort */
  279.     bounds = pWindow->portRect;
  280.     InsetRect (&bounds, FixedToInt (kFrameThickness), FixedToInt (kFrameThickness));
  281.     width    = IntToFixed (bounds.right  - bounds.left) / numCols;
  282.     height    = IntToFixed (bounds.bottom - bounds.top)  / numRows;
  283.  
  284.     /* Make a gxTransform */
  285.     xForm = GXNewTransform ();
  286.  
  287.     /* Allocate space for viewPorts */
  288.     p1stViewPort = pViewPort = (gxViewPort *) NewPtr (numRows * numCols * sizeof (gxViewPort));
  289.     if (p1stViewPort == nil)
  290.     {
  291.         DebugStr ("\pAddViewPortsToTransform: NewPtr for viewPorts failed");
  292.         return;
  293.     }
  294.  
  295.     parent = GXGetWindowViewPort (pWindow);
  296.  
  297.     for (r = 0, top = kFrameThickness; r < numRows; r++, top += height)
  298.     {
  299.         for (c = 0, left = kFrameThickness; c < numCols; c++, left += width, pViewPort++)
  300.         {
  301.             /* Make a new gxViewPort and set its clip and gxMapping */
  302.             *pViewPort = GXNewViewPort (gxScreenViewDevices);
  303.             GXSetViewPortParent (*pViewPort, parent);
  304.  
  305.             /* Make and set the gxViewPort's clip */
  306.             clip = NewShape4 (gxRectangleType, left, top, left + width, top + height);
  307.             if (showFrame)
  308.                 GXInsetShape (clip, kFrameThickness);
  309.             GXSetViewPortClip (*pViewPort, clip);
  310.             GXDisposeShape (clip);
  311.  
  312.             /* Set the dither or gxHalftone and gxMapping */
  313.             SetDitherOrHalftone (*pViewPort, r, c);
  314.             SetMapping (*pViewPort, r, c, left + (width >> 1), top + (height >> 1));
  315.  
  316.             if (r == 0  &&  c == 0)
  317.                 /* Set the gxTransform's first gxViewPort */
  318.                 GXSetTransformViewPorts (xForm, 1, pViewPort);
  319.             else
  320.                 /* Add successive viewPorts */
  321.                 AddToTransformViewPort (xForm, *pViewPort);
  322.         }
  323.     }
  324.  
  325.     /* Set the object gxShape's gxTransform with all the gxViewPort */
  326.     GXSetShapeTransform (object, xForm);
  327.     GXDisposeTransform (xForm);
  328. }
  329.  
  330.  
  331.     void
  332. InitializeViewPortGlobals (void)
  333. {
  334.     gShowFrame      = true;
  335.     gDoAnimation  = false;
  336.     gDoDither      = true;
  337.     gDoHalftone      = true;
  338.     gIsSquare     = true;
  339.     gObject          = nil;
  340.     gFrame          = nil;
  341.     gPanesPerSide = kInitialPanesPerSide;
  342.     gCyclePanes      = false;
  343.     gNextCycle      = 0;
  344. }
  345.  
  346.  
  347.     void
  348. ChangeViewPorts (WindowPtr pWindow)
  349. {
  350.     ChangeShapeViewPorts (pWindow, gPanesPerSide, gPanesPerSide, gShowFrame, gObject);
  351.     ChangeFrame (&pWindow->portRect, gPanesPerSide, gPanesPerSide, gShowFrame, &gFrame);
  352. }
  353.  
  354.  
  355.     void
  356. InitializeViewPorts (WindowPtr pWindow)
  357. {
  358.     InitializeObject (gIsSquare, kObjectWidth, kObjectHeight, &gObject, &gLastObject);
  359.     ChangeViewPorts (pWindow);
  360. }
  361.  
  362.     void
  363. DisposeViewPorts (WindowPtr pWindow)
  364. {
  365.     gxViewPort    parent,
  366.                 *p1stChild,
  367.                 *pChild;
  368.     long        childCount;
  369.  
  370.     DisposeShapeAt (&gObject);
  371.     DisposeShapeAt (&gLastObject);
  372.     DisposeShapeAt (&gFrame);
  373.  
  374.     if (parent = GXGetWindowViewPort (pWindow))
  375.     {
  376.         if (childCount = GXGetViewPortChildren (parent, nil))
  377.         {
  378.             if (p1stChild = pChild = (gxViewPort *) NewPtrClear (childCount * sizeof (gxViewPort)))
  379.             {
  380.                 (void) GXGetViewPortChildren (parent, p1stChild);
  381.                 while (childCount--)
  382.                     GXDisposeViewPort (*pChild++);
  383.                 DisposePtr ((Ptr) p1stChild);
  384.                 GXDisposeViewPort (parent);
  385.             }
  386.             else
  387.                 DebugStr ("\pDisposeViewPorts: NewPtrClear failed");
  388.         }
  389.         else
  390.             DebugStr ("\pDisposeViewPorts: Parent gxViewPort has no children");
  391.     }
  392.     else
  393.         DebugStr ("\pDisposeViewPorts: Window has no gxViewPort");
  394. }
  395.